#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=favicon.ico
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Description=Script to install all needed software on new computers
#AutoIt3Wrapper_Res_Fileversion=0.7.1.7
#AutoIt3Wrapper_Res_FileVersion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=John Seekins
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_res_requestedExecutionLevel=requireAdministrator
#AutoIt3Wrapper_Res_Icon_Add=favicon.ico
#AutoIt3Wrapper_Res_File_Add=Recovery Console Install.exe
#AutoIt3Wrapper_Res_File_Add=InstallBGInfo.exe
#AutoIt3Wrapper_Run_Tidy=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; *** Start added by AutoIt3Wrapper ***
#include <GUIConstantsEx.au3>
; *** End added by AutoIt3Wrapper ***
#comments-start
	Copyright (c) <2011>, <John Seekins>
	All rights reserved.
	
	Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
	
	* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
	* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
	* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
	
	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#comments-end
#Region Include Statements
#include <GUIConstants.au3>
#include <Process.au3>
#EndRegion Include Statements

Opt("GUICloseOnESC", 0)
#Region Variable Declarations
Const $programTitle = "Network AutoInstaller"
Const $logFile = @WindowsDir & "\autoinstallerlog.ini"
Dim $iniFile = @ScriptDir & "\autoinstaller.ini"

; read in data from the defined .ini file
$iniSections = IniRead($iniFile, "Global", "IniSections", "6")
$networkedInstall = IniRead($iniFile, "Global", "NetworkInstall", 1)
;persistent network variables (i.e. always read from [Network]
$serverName = "\\" & IniRead($iniFile, "Network", "ServerName", "")
$installDrive = IniRead($iniFile, "Network", "InstallDrive", "Z:")
$patchesDrive = IniRead($iniFile, "Network", "patchesDrive", "Y:")
;end persistent network variables (i.e. always read from [Network]
$installFolder = getInstallFolderLoc($iniFile, $networkedInstall, $serverName)
$patchesFolder = getPatchesFolderLoc($iniFile, $networkedInstall, $serverName)

$copyLocation = testCopyLocation(IniRead($iniFile, "General", "BINDir", "D:\BIN"))
$patchesSetup = IniReadSection($iniFile, "Patches")
$installSetup = IniReadSection($iniFile, "Installs")
$copyInstllData = IniRead($iniFile, "Global", "CopyInstallData", 1)
$newAdminPass = IniRead($iniFile, "Global", "NewAdminPass", "")
$installRecoveryConsole = IniRead($iniFile, "Global", "RecoveryConsole", 0)

;basic positioning variables for GUI design
$BaseX = 20
$BaseY = 40
$CurX = 0
$CurY = 0

;general variables and networking variables
$msg = "" ;GUI message handling variable
$ret = 0 ; return value for functions
$reboot = 0 ;should the machine reboot after the script is run?
Dim $driveMapErrors[6]
$driveMapErrors[0] = "Undefined or Other"
$driveMapErrors[1] = "Access to the remote share was denied"
$driveMapErrors[2] = "The device is already assigned"
$driveMapErrors[3] = "Invalid device name"
$driveMapErrors[4] = "Invalid remote share"
$driveMapErrors[5] = "Invalid password"
#EndRegion Variable Declarations

$hGUI = GUICreate($programTitle, 260, 320)
Opt("GUICoordMode", 1)

#Region Drop-Down Menu
$fileMenu = GUICtrlCreateMenu("&File")
$iniLoadMenuItem = GUICtrlCreateMenuItem("&Load Ini File", $fileMenu)
$exitProgramMenuItem = GUICtrlCreateMenuItem("E&xit", $fileMenu)
$toolsMenu = GUICtrlCreateMenu("&Tools")
$recConsoleInstallMenuItem = GUICtrlCreateMenuItem("&Install Recovery Console", $toolsMenu)
$helpMenu = GUICtrlCreateMenu("&Help")
$aboutMenuItem = GUICtrlCreateMenuItem("About...", $helpMenu)
#EndRegion Drop-Down Menu

$GUITab = GUICtrlCreateTab(10, 10, 245, 285)

#Region Create Install Tab
$GUITabInstall = GUICtrlCreateTabItem("Install")
$CurX = $BaseX
$CurY = $BaseY
$computerTypeHomeRadio = GUICtrlCreateRadio("Home System", $CurX, $CurY)
$CurY += 25
$computerTypeWorkRadio = GUICtrlCreateRadio("Business System", $CurX, $CurY)
$CurY += 35
$copyToHDDCheckbox = GUICtrlCreateCheckbox("Copy Install Data to HDD?", $CurX, $CurY)
$CurY += 35
GUICtrlCreateLabel("Destination for BIN directory:", $CurX, $CurY)
$CurY += 20
$copyLocationInput = GUICtrlCreateInput($copyLocation, $CurX, $CurY, 150)
$CurX += 160
$browseCopyLocation = GUICtrlCreateButton("Browse...", $CurX, $CurY - 3)
$CurX = $BaseX
$CurY += 45
GUICtrlCreateLabel("Current Loaded .ini File:", $CurX, $CurY)
$CurY += 20
$iniDisplayInput = GUICtrlCreateInput($iniFile, $CurX, $CurY, 220)
$CurX = $BaseX
$CurY += 40
$CurX += 64
$executeButton = GUICtrlCreateButton("Install Software", $CurX, $CurY)

GUICtrlSetTip($iniDisplayInput, $iniFile)
#EndRegion Create Install Tab
#Region Options Tab
$GUITabOptions = GUICtrlCreateTabItem("Options")
$CurX = $BaseX
$CurY = $BaseY
If (@OSVersion = "WIN_XP") Or (@OSVersion = "WIN_2000") Then
	$installRecoveryConsoleCheckbox = GUICtrlCreateCheckbox("Install Recovery Console?", $CurX, $CurY)
	$CurY += 35
	$installTweakUICheckbox = GUICtrlCreateCheckbox("Install TweakUI?", $CurX, $CurY)
	$CurY += 35
EndIf
$changeAdminPasswordCheckbox = GUICtrlCreateCheckbox("Change Administrator Password?", $CurX, $CurY)
$CurY += 35
$installRegistryTweaksCheckbox = GUICtrlCreateCheckbox("Add resgistry tweaks?", $CurX, $CurY)
$CurY += 35
$disableHibernationCheckbox = GUICtrlCreateCheckbox("Disable system hibernation?", $CurX, $CurY)
#EndRegion Options Tab

GUISetState()
GUICtrlSetState($computerTypeHomeRadio, $GUI_CHECKED)
GUICtrlSetState($copyToHDDCheckbox, $GUI_CHECKED)
If (@OSVersion = "WIN_XP") Or (@OSVersion = "WIN_2000") Then
	GUICtrlSetState($installRecoveryConsoleCheckbox, $GUI_CHECKED)
	GUICtrlSetState($installTweakUICheckbox, $GUI_CHECKED)
EndIf
GUICtrlSetState($installRegistryTweaksCheckbox, $GUI_CHECKED)
GUICtrlSetState($changeAdminPasswordCheckbox, $GUI_CHECKED)
GUICtrlSetState($disableHibernationCheckbox, $GUI_CHECKED)

#Region Pre-GUI Tests
;test for Windows Installer 3.1.  Most of the patches you'd likely be running now will require this.
$msiVerString = Number(FileGetVersion(@SystemDir & "\msi.dll"))
If ($msiVerString < 3.1) And ((@OSVersion = "WIN_XP") Or (@OSVersion = "WIN_2000")) Then
	MapDrives()
	MsgBox(48, "Incompatible Windows Installer!", "This program requires Windows Installer 3.1 or greater to function" & @LF & @LF & "This program will now be installed and the computer restarted.")
	installItem($patchesDrive, IniRead($iniFile, "Installer", "Windows Installer 3.1", "WindowsInstaller-3.1.exe /passive"))
	$msg = $GUI_EVENT_CLOSE
	Shutdown(2)
	;has this program been run before?  Did it finish?
	;if it didn't finish, re-run what's left to do.
ElseIf FileExists($logFile) Then
	If IniRead($logFile, "Global", "Completed", 0) = 1 Then
		If MsgBox(36, "Run Completed Script Again?", "This program has completed successfully in the past.  Would you like to re-run it?") = 7 Then $msg = $GUI_EVENT_CLOSE
	Else
		If MsgBox(36, "Continue Unfinished Run?", "This program has been run in the past but did not complete successfully.  Would you like to attempt to finish it?") = 6 Then
			LoadINIFile($logFile)
			If (@OSVersion = "WIN_XP") Or (@OSVersion = "WIN_2000") Then
				$installRecoveryConsole = IniRead($logFile, "Other", "InstallRecoveryConsole", 1)
			Else
				$installRecoveryConsole = 0
			EndIf
			If $serverName = "\\" & IniRead($iniFile, "Global", "NetworkInstall", 0) = 1 Then MapDrives()
			If IniRead($logFile, "Other", "BusinessMachine", 0) = 1 Then
				GUICtrlSetState($computerTypeHomeRadio, $GUI_UNCHECKED)
				GUICtrlSetState($computerTypeWorkRadio, $GUI_CHECKED)
			EndIf
			modCallingWindow($programTitle, @SW_MINIMIZE)
			$ret = executeInstallCommands($patchesFolder, $patchesSetup, $installFolder, $installSetup, GUICtrlRead($computerTypeWorkRadio), _
					GUICtrlRead($copyToHDDCheckbox), $copyLocation, $logFile, $newAdminPass, $installRecoveryConsole, $networkedInstall)
			modCallingWindow($programTitle, @SW_RESTORE)
			$msg = $GUI_EVENT_CLOSE
			Switch $ret
				Case 0
					MsgBox(64, "Completed Installation", "Successfully completed installation and copying procedures...")
					If MsgBox(36, "Restart machine?", "Would you like to restart the machine now?") = 6 Then $reboot = 1
				Case 1
					ProgressOff()
					MsgBox(48, "Failed Networking!", "Networking drives to install directories failed...")
				Case 2
					ProgressOff()
					MsgBox(48, "Failed Networking!", "Lost connection to server during file operations!" & @LF & "Please restart the machine and start the script over...")
					If MsgBox(36, "Restart Machine?", "Would you like to restart the machine now?") = 6 Then $reboot = 1
			EndSwitch
		EndIf
	EndIf
EndIf
#EndRegion Pre-GUI Tests

; Run the GUI until the dialog is closed
While $msg <> $GUI_EVENT_CLOSE
	$msg = GUIGetMsg()

	Switch $msg ;user actions are stored in $msg, parse possible re-actions here:
		Case $aboutMenuItem
			MsgBox(0, "RAM Computers AutoInstaller", "Version: " & FileGetVersion("AutoInstaller.exe"))

		Case $exitProgramMenuItem
			$msg = $GUI_EVENT_CLOSE

		Case $iniLoadMenuItem
			$iniFile = FileOpenDialog("Select config file", @ScriptDir, "INI files (*.ini)", 1)
			If $iniFile Then LoadINIFile($iniFile)

		Case $recConsoleInstallMenuItem
			If (@OSVersion = "WIN_XP") Or (@OSVersion = "WIN_2000") Then
				FileInstall("Recovery Console Install.exe", @TempDir & "\Recovery Console Install.exe", 1)
				ShellExecuteWait(@TempDir & "\Recovery Console Install.exe")
				FileDelete(@TempDir & "\Recovery Console Install.exe")
			Else
				MsgBox(64, "Recovery Console Not Supported", "Cannot install the Microsoft Recovery Console in this version of Windows!", 5)
			EndIf

		Case $browseCopyLocation
			$copyLocation = browseFolder()
			If StringCompare($copyLocation, "") <> 0 Then
				GUICtrlSetData($copyLocationInput, $copyLocation)
			Else
				$copyLocation = GUICtrlRead($copyLocationInput)
			EndIf

		Case $executeButton
			modCallingWindow($programTitle, @SW_MINIMIZE)
			$copyLocation = testCopyLocation(GUICtrlRead($copyLocationInput))
			$ret = executeInstallCommands($patchesFolder, $patchesSetup, $installFolder, $installSetup, GUICtrlRead($computerTypeWorkRadio), GUICtrlRead($copyToHDDCheckbox), $copyLocation, $logFile, $newAdminPass, $installRecoveryConsole, $networkedInstall)
			modCallingWindow($programTitle, @SW_RESTORE)
			$msg = $GUI_EVENT_CLOSE
			Switch $ret
				Case 0
					MsgBox(64, "Completed Installation", "Successfully completed installation and copying procedures...")
					If MsgBox(36, "Restart machine?", "Would you like to restart the machine now?") = 6 Then $reboot = 1
				Case 1
					ProgressOff()
					MsgBox(48, "Failed Networking!", "Networking drives to install directories failed..." & @LF & "Are you connected to the server properly?")
				Case 2
					ProgressOff()
					MsgBox(48, "Failed Networking!", "Lost connection to server during file operations!" & @LF & "Please restart the machine and start the script over...")
					If MsgBox(36, "Restart Machine?", "Would you like to restart the machine now?") = 6 Then $reboot = 1
			EndSwitch
	EndSwitch
WEnd

DriveMapDel($installDrive)
DriveMapDel($patchesDrive)
GUIDelete()
If $reboot = 1 Then Shutdown(2)

#Region General Functions
Func LoadINIFile($iniFile)
	;determine whether the sections with in the ini file are correct for this particular ini load
	$iniSectionList = IniReadSectionNames($iniFile)
	$iniSections = IniRead($iniFile, "Global", "IniSections", "6")
	If $iniSectionList[0] = $iniSections And $iniSectionList[1] = "Global" Then
		$iniSections = IniRead($iniFile, "Global", "IniSections", "6")
		$networkedInstall = IniRead($iniFile, "Global", "NetworkInstall", 1)
		;persistent network variables (i.e. always read from [Network])
		$serverName = "\\" & IniRead($iniFile, "Network", "ServerName", "")
		$installDrive = IniRead($iniFile, "Network", "InstallDrive", "Z:")
		$patchesDrive = IniRead($iniFile, "Network", "patchesDrive", "Y:")
		;end persistent network variables (i.e. always read from [Network]
		$installFolder = getInstallFolderLoc($iniFile, $networkedInstall, $serverName)
		$patchesFolder = getPatchesFolderLoc($iniFile, $networkedInstall, $serverName)

		$copyLocation = testCopyLocation(IniRead($iniFile, "Network", "BINDir", "D:\BIN"))
		GUICtrlSetData($copyLocationInput, $copyLocation)
		$patchesSetup = IniReadSection($iniFile, "Patches")
		$installSetup = IniReadSection($iniFile, "Installs")
		$copyInstllData = IniRead($iniFile, "Global", "CopyInstallData", 1)
		$newAdminPass = IniRead($iniFile, "Global", "NewAdminPass", "")
		If (@OSVersion = "WIN_XP") Or (@OSVersion = "WIN_2000") Then
			$installRecoveryConsole = IniRead($logFile, "Other", "InstallRecoveryConsole", 0)
			If $installRecoveryConsole = 0 Then
				GUISetState($installRecoveryConsoleCheckbox, $GUI_UNCHECKED)
			Else
				GUISetState($installRecoveryConsoleCheckbox, $GUI_CHECKED)
			EndIf
		Else
			$installRecoveryConsole = 0
		EndIf
		MsgBox(64, "ini File Load Complete", "Loaded .ini file " & $iniFile, 5)
		GUICtrlSetData($iniDisplayInput, $iniFile)
		GUICtrlSetTip($iniDisplayInput, $iniFile)
	Else
		MsgBox(48, "Invalid Program INI File", "The file you selected does not contain the proper formatting for loading as an INI file")
	EndIf
EndFunc   ;==>LoadINIFile

#Region Getters and Setters
Func getPatchesFolderLoc($iniFile, $network, $serverName)
	If $network Then
		Return $serverName & "\" & IniRead($iniFile, "Network", "PatchesFolder", "patches")
	Else
		Return IniRead($iniFile, "Local", "PatchesFolder", "patches")
	EndIf
EndFunc   ;==>getPatchesFolderLoc

Func getInstallFolderLoc($iniFile, $network, $serverName)
	If $network Then
		Return $serverName & "\" & IniRead($iniFile, "Network", "InstallFolder", "install")
	Else
		Return IniRead($iniFile, "Local", "InstallFolder", "install")
	EndIf
EndFunc   ;==>getInstallFolderLoc
#EndRegion Getters and Setters

Func IsVisible($handle)
	If BitAND(WinGetState($handle), 2) Then
		Return 1
	Else
		Return 0
	EndIf
EndFunc   ;==>IsVisible

Func modCallingWindow($title, $state)
	Local $activeWindowList = WinList()
	Local $windowNumber = 0
	For $i = 1 To $activeWindowList[0][0]
		If $activeWindowList[$i][0] <> "" And IsVisible($activeWindowList[$i][1]) Then
			Local $windowTitle = StringTrimLeft($activeWindowList[$i][0], StringLen($activeWindowList[$i][0]) - StringLen($title))
			If $windowTitle = $title Then
				$windowNumber = $i
				WinSetState($activeWindowList[$i][0], "", $state)
			EndIf
		EndIf
	Next
EndFunc   ;==>modCallingWindow
#EndRegion General Functions

#Region Disk Functions
Func browseFolder()
	Local $tempFolder = ""
	$tempFolder = FileSelectFolder("Select Location for BIN Directory:", "")
	Return $tempFolder
EndFunc   ;==>browseFolder

Func testCopyLocation($tempCopy)
	Local $driveLetter = StringLeft($tempCopy, 2)
	If StringCompare(DriveGetType($driveLetter), "Fixed") <> 0 Then
		$driveLetter = findFixedDrive()
		If StringCompare($driveLetter, "") = 0 Then
			MsgBox(48, "No Fixed Drives Found!", "How can you be running this program?!?!" & @LF & "Now exiting...")
			Exit (1)
		Else
			Return $driveLetter & "\BIN"
		EndIf
	Else
		Return $tempCopy
	EndIf
EndFunc   ;==>testCopyLocation

Func findFixedDrive()
	Local $driveArray
	$driveArray = DriveGetDrive("FIXED")
	If IsArray($driveArray) = 0 Then
		Return ""
	Else
		Return StringUpper($driveArray[1])
	EndIf
EndFunc   ;==>findFixedDrive

Func MapDrives()
	DriveMapDel($installDrive)
	DriveMapDel($patchesDrive)
	$res = DriveMapAdd($installDrive, $installFolder)
	If $res <> 1 Then
		SplashOff()
		MsgBox(16, "Drive Mapping", "Error mapping drive!" & @LF & "Error Code: " & $driveMapErrors[@error])
		Return $res
	EndIf
	$res = DriveMapAdd($patchesDrive, $patchesFolder)
	If $res <> 1 Then
		SplashOff()
		MsgBox(16, "Drive Mapping", "Error mapping drive!" & @LF & "Error Code: " & $driveMapErrors[@error])
		Return $res
	EndIf
	Return $res
EndFunc   ;==>MapDrives
#EndRegion Disk Functions

#Region Install Functions
Func executeInstallCommands($winPatchesFolder, $winPatchesArray, $winInstFolder, $winInstArray, $workMachine, $copyData, $instCopyLoc, $logFile, $newAdminPass, $installRecoveryConsole, $networkInstall)
	Local $rc = 0
	Local $sAdditionalInstalls = ""

	If (@OSVersion = "WIN_XP") Or (@OSVersion = "WIN_2000") Then
		If ($installRecoveryConsole <> 0) And (GUICtrlRead($installRecoveryConsoleCheckbox) = $GUI_CHECKED) Then
			FileInstall("Recovery Console Install.exe", @TempDir & "\Recovery Console Install.exe", 1)
			ShellExecuteWait(@TempDir & "\Recovery Console Install.exe")
			FileDelete(@TempDir & "\Recovery Console Install.exe")
		EndIf
	EndIf

	IniWrite($logFile, "Global", "Completed", 0)
	ProgressOn("Installing patches and software...", "Mapping Network Drives...", "", 0, 0, 2)
	If $networkInstall Then
		If MapDrives() = 0 Then
			IniWrite($logFile, "Other", "InstallRecoveryConsole", 0)
			IniWrite($logFile, "Global", "NetworkInstall", $networkInstall)
			IniWriteSection($logFile, "PatchesList", $winPatchesArray)
			If $copyData = $GUI_CHECKED Then IniWrite($logFile, "DataCopy", "Completed", 0)
			IniWriteSection($logFile, "InstallsList", $winInstArray)
			If $workMachine = $GUI_CHECKED Then IniWrite($logFile, "Other", "BusinessMachine", 1)
			Return 1 ;error mapping network drives
		EndIf
	EndIf
	;install system patches (IE, WMP, .NET framework, etc.)
	If IsArray($winPatchesArray) Then
		$rc = processInstall($winPatchesArray, $winPatchesFolder, "Installing Windows Patches", 20, $networkInstall)
		If $rc <> 0 Then
			IniWrite($logFile, "Other", "InstallRecoveryConsole", 0)
			For $i = $rc To $winPatchesArray[0][0]
				$sAdditionalInstalls &= $winPatchesArray[$i][0] & "=" & $winPatchesArray[$i][1] & @LF
			Next
			IniWrite($logFile, "Global", "NetworkInstall", $networkInstall)
			IniWriteSection($logFile, "PatchesList", $sAdditionalInstalls)
			If $copyData = $GUI_CHECKED Then IniWrite($logFile, "DataCopy", "Completed", 0)
			IniWriteSection($logFile, "InstallsList", $winInstArray)
			If $workMachine = $GUI_CHECKED Then IniWrite($logFile, "Other", "BusinessMachine", 1)
			Return 2
		EndIf
	EndIf
	;copy data from install folder to HDD
	If (StringCompare($instCopyLoc, "") <> 0) And ($copyData = $GUI_CHECKED) Then
		ProgressSet(33, "Copying install folder to " & $instCopyLoc, "Copying installation data...")
		If (DirCopy($winInstFolder, $instCopyLoc, 1) = 0) And ($networkInstall = 1) Then
			IniWrite($logFile, "Other", "InstallRecoveryConsole", 0)
			IniWrite($logFile, "Global", "NetworkInstall", $networkInstall)
			If $copyData = $GUI_CHECKED Then IniWrite($logFile, "DataCopy", "Completed", 0)
			IniWriteSection($logFile, "InstallsList", $winInstArray)
			If $workMachine = $GUI_CHECKED Then IniWrite($logFile, "Other", "BusinessMachine", 1)
			Return 2
		EndIf
	EndIf
	;install software packages (7-zip, Firefox, etc.)
	If IsArray($winInstArray) Then
		$rc = processInstall($winInstArray, $winInstFolder, "Installing Software", 66, $networkInstall)
		If $rc <> 0 Then
			For $i = $rc To $winInstArray[0][0]
				$sAdditionalInstalls &= $winInstArray[$i][0] & "=" & $winInstArray[$i][1] & @LF
			Next
			IniWrite($logFile, "Other", "InstallRecoveryConsole", 0)
			IniWrite($logFile, "Network", "NetworkInstall", $networkInstall)
			IniWriteSection($logFile, "InstallsList", $sAdditionalInstalls)
			If $workMachine = $GUI_CHECKED Then IniWrite($logFile, "Other", "BusinessMachine", 1)
			Return 2
		EndIf
	EndIf
	;copy TweakUI to computer
	If (@OSVersion = "WIN_XP") Or (@OSVersion = "WIN_2000") Then
		If (FileExists($winInstFolder & "\TweakUI.exe")) And (GUICtrlRead($installTweakUICheckbox) = $GUI_CHECKED) Then
			If Not FileCopy($winInstFolder & "\TweakUI.exe", @SystemDir, 1) Then
				IniWrite($logFile, "Other", "InstallRecoveryConsole", 0)
				IniWrite($logFile, "Network", "NetworkInstall", $networkInstall)
				IniWrite($logFile, "Other", "BusinessMachine", $workMachine)
				Return 2
			EndIf
			FileCreateShortcut(@SystemDir & "\TweakUI.exe", @StartMenuDir & "\TweakUI.lnk")
		EndIf
	EndIf
	;set administrator password
	If (StringCompare($newAdminPass, "") <> 0) And (GUICtrlRead($changeAdminPasswordCheckbox) = $GUI_CHECKED) Then
		_RunDOS("NET USER administrator " & $newAdminPass)
	EndIf
	;configure Spybot S&D
	;If FileExists(@ProgramFilesDir & "\Spybot - Search & Destroy\SpybotSD.exe") Then spybotInstall()

	ProgressSet(90, " ", "Extra Configuration...")
	If GUICtrlRead($installRegistryTweaksCheckbox) = $GUI_CHECKED Then registryConfig()
	;add system information into computer background
	If ($workMachine = $GUI_CHECKED) Then
		FileInstall("InstallBGInfo.exe", @TempDir & "\InstallBGInfo.exe")
		ShellExecuteWait(@TempDir & "\InstallBGInfo.exe")
		FileDelete(@TempDir & "\InstallBGInfo.exe")
	EndIf
	;hibernation config
	If GUICtrlRead($disableHibernationCheckbox) = $GUI_CHECKED Then _RunDOS("powercfg -h off")

	ProgressSet(100, "Done", "Completed!")
	ProgressOff()
	IniWrite($logFile, "Global", "Completed", 1)
	Return 0
EndFunc   ;==>executeInstallCommands

Func registryConfig()
	;increase number of concurrent network connections
	RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings", "MaxConnectionsPerServer", "REG_DWORD", 00000010)
	RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings", "MaxConnectionsPer1_0Server", "REG_DWORD", 00000010)
	RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment", "DEVMGR_SHOW_NONPRESENT_DEVICES", "REG_SZ", "1")
	;remove language bar
	_RunDOS("regsvr32.exe /u /s msutb.dll")
	_RunDOS("regsvr32.exe /u /s Msimtf.dll")
	_RunDOS("regsvr32.exe /u /s Msctf.dll")
	_RunDOS("cscript " & @SystemDir & '\prnmngr.vbs -d -p "Microsoft XPS Document Writer"')
	RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem", "NtfsDisableCompression", "REG_DWORD", 00000001)
EndFunc   ;==>registryConfig

#comments-start ---------
	Spybot currently has problems with randomly enabling the "Teatimer" portion of the program.
	Because this functionality doesn't work with any anti-virus, we won't be installing the program.
	Func spybotInstall()
	ProgressSet(80, "", "Updating and Immunizing with Spybot Search & Destroy")
	;Configure spybot to not show the wizard, legal notice, or update reminder
	RegWrite('HKEY_CURRENT_USER\Software\Safer Networking Limited\SpybotSnD', 'WizardRun', 'REG_DWORD', 1)
	IniWrite(@AppDataCommonDir & '\Spybot - Search & Destroy\Configuration.ini', 'Main', 'Legals', 1)
	IniWrite(@AppDataCommonDir & '\Spybot - Search & Destroy\Configuration.ini', 'Automation\WebUpdate', 'RemindUpdate', 0)
	
	ProgressSet(81, "Updating...", "Updating and Immunizing with Spybot Search & Destroy")
	ShellExecuteWait(@ProgramFilesDir & "\Spybot - Search & Destroy\SpybotSD.exe", "/taskbarhide /autoupdate /autoclose")
	ProgressSet(85, "Immunizing...", "Updating and Immunizing with Spybot Search & Destroy")
	ShellExecuteWait(@ProgramFilesDir & "\Spybot - Search & Destroy\SpybotSD.exe", "/taskbarhide /autoimmunize /autoclose")
	EndFunc   ;==>spybotInstall
#comments-end -----------

#cs ----------------------
	Since there is a possibility that we could lose connection to the "server" (either directory or actual physically remote computer)
	that we are trying to install from, there should be some sort of graceful error reporting of that failure.
	ShellExecuteWait throws errors into the @error macro if the program called within it exits incorrectly.  So a program that did not
	run at all could be considered one that did not run correctly.  It follows that the proper error testing for a failed server connection
	would be to see if we can run a program from that "server".  If we can't, we have to assume that the network connection is lost.
#ce ----------------------
Func installItem($installPath, $installString)
	Local $stringSpace = ""
	Local $parametersString = ""

	$stringSpace = StringSplit($installString, " /", 1)
	If $stringSpace[0] > 1 Then
		$parametersString = "/" & $stringSpace[2]
		For $j = 3 To $stringSpace[0]
			$parametersString &= " /" & $stringSpace[$j]
		Next
	EndIf
	;because $parametersString is only "" unless the actual install string has parameters (as tested by $stringSpace)
	;we can simply call the function once, rather than two different times
	ShellExecuteWait($installPath & "\" & $stringSpace[1], $parametersString)
	If @error <> 0 Then Return 0
	Return 1
EndFunc   ;==>installItem

Func processInstall($aInstallList, $sInstallFolder, $sProgressString, $dProgressAmount, $networkInstall)
	ProgressSet($dProgressAmount, "", $sProgressString)
	For $i = 1 To $aInstallList[0][0]
		ProgressSet($dProgressAmount + $i, "Installing " & $aInstallList[$i][0])
		If (installItem($sInstallFolder, $aInstallList[$i][1]) = 0) And ($networkInstall = 1) Then Return $i
	Next
	Return 0
EndFunc   ;==>processInstall
#EndRegion Install Functions